package com.relife.common.file;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Iterator;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;

import com.relife.common.exception.BusinessException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

@SuppressWarnings("restriction")
public class ImageUtil {

	/**
	 * 
	 * @author WU
	 * @date 2014-11-10 下午2:40:22
	 * @param savePath
	 * @deprecated(压缩背景透明图片背景会变黑)
	 */
	public static void imgCompression(InputStream input, String savePath) {
		try {
			BufferedImage image = ImageIO.read(input);
			FileOutputStream s = new FileOutputStream(savePath);
			s.write(bufferedImageTobytes(image, 0.15f));
			s.flush();
			s.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * 自己设置压缩质量来把图片压缩成byte[]
	 * 
	 * @param image
	 *            压缩源图片
	 * @param quality
	 *            压缩质量，在0-1之间，
	 * @return 返回的字节数组
	 */
	private static byte[] bufferedImageTobytes(BufferedImage image, float quality) {
		System.out.println("jpeg" + quality + "质量开始打包" + getCurrentTime());
		// 如果图片空，返回空
		if (image == null) {
			return null;
		}

		// 得到指定Format图片的writer
		Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpeg");// 得到迭代器
		ImageWriter writer = (ImageWriter) iter.next(); // 得到writer

		// 得到指定writer的输出参数设置(ImageWriteParam )
		ImageWriteParam iwp = writer.getDefaultWriteParam();
		iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // 设置可否压缩
		iwp.setCompressionQuality(quality); // 设置压缩质量参数

		iwp.setProgressiveMode(ImageWriteParam.MODE_DISABLED);

		ColorModel colorModel = ColorModel.getRGBdefault();
		// 指定压缩时使用的色彩模式
		iwp.setDestinationType(new javax.imageio.ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel(16, 16)));

		// 开始打包图片，写入byte[]
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // 取得内存输出流
		IIOImage iIamge = new IIOImage(image, null, null);
		try {
			// 此处因为ImageWriter中用来接收write信息的output要求必须是ImageOutput
			// 通过ImageIo中的静态方法，得到byteArrayOutputStream的ImageOutput
			writer.setOutput(ImageIO.createImageOutputStream(byteArrayOutputStream));
			writer.write(null, iIamge, iwp);
		} catch (IOException e) {
			System.out.println("write errro");
			e.printStackTrace();
		}
		System.out.println("jpeg" + quality + "质量完成打包-----" + getCurrentTime() + "----lenth----" + byteArrayOutputStream.toByteArray().length);
		return byteArrayOutputStream.toByteArray();
	}

	/**
	 * 自己定义格式，得到当前系统时间
	 * 
	 * @return
	 */
	private static String getCurrentTime() {
		Calendar c = new GregorianCalendar();
		int hour = c.get(Calendar.HOUR_OF_DAY);
		int min = c.get(Calendar.MINUTE);
		int second = c.get(Calendar.SECOND);
		int millsecond = c.get(Calendar.MILLISECOND);
		String time = hour + "点" + min + "分" + second + "秒" + millsecond;
		return time;
	}

	/**
	 * 图片压缩
	 * 
	 * @author WU
	 * @date 2015-4-23 下午4:50:49
	 * @param outPath
	 * @param w
	 * @param h
	 */
	public static void compressPic(InputStream in, String outPath, int w, int h) {
		try {
			Image img = ImageIO.read(in);
			// 判断图片格式是否正确
			if (img.getWidth(null) == -1) {
				throw new Exception("图片格式有误");
			} else {
				BufferedImage tag = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
				// Image.SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好 但速度慢
				tag.getGraphics().drawImage(img.getScaledInstance(w, h, Image.SCALE_SMOOTH), 0, 0, null);
				FileOutputStream out = new FileOutputStream(outPath);
				// JPEGImageEncoder可适用于其他图片类型的转换
				JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
				encoder.encode(tag);
				out.flush();
				out.close();
				tag.flush();
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 等比压缩
	 * 
	 * @author WU
	 * @date 2015-4-23 下午6:00:42
	 * @param outPath
	 * @throws FileNotFoundException
	 */
	public static void compressPicMaxWidth(InputStream in, String outPath, int maxWidth) throws Exception {
		Image img = ImageIO.read(in);
		if (img == null) {
			throw new BusinessException("未能识别的图片！");
		}
		// 判断图片格式是否正确
		float w = img.getWidth(null);
		float h = img.getHeight(null);
		if (w == -1) {
			throw new BusinessException("图片格式有误");
		}
		FileOutputStream out = new FileOutputStream(outPath);
		if (w > maxWidth) {
			h = maxWidth / w * h;
			w = maxWidth;
			// Image.SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好 但速度慢
			img = img.getScaledInstance((int) w, (int) h, Image.SCALE_SMOOTH);

		}
		BufferedImage tag = new BufferedImage((int) w, (int) h, BufferedImage.TYPE_INT_RGB);
		tag.getGraphics().drawImage(img, 0, 0, null);
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
		encoder.encode(tag);
		out.flush();
		out.close();
		tag.flush();
		img.flush();
	}

	/**
	 * 图片压缩(图片宽高不变)
	 * 
	 * @author WU
	 * @date 2015-4-23 下午6:00:42
	 * @param outPath
	 */
	public static void compressPic(InputStream in, String outPath) {
		try {
			Image img = ImageIO.read(in);
			if (img == null) {
				throw new BusinessException("未能识别的图片！");
			}
			// 判断图片格式是否正确
			int width = img.getWidth(null);
			int height = img.getHeight(null);
			if (width == -1) {
				throw new BusinessException("图片格式有误");
			} else {
				BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
				// Image.SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好 但速度慢
				tag.getGraphics().drawImage(img.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
				FileOutputStream out = new FileOutputStream(outPath);
				// JPEGImageEncoder可适用于其他图片类型的转换
				JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
				encoder.encode(tag);
				out.flush();
				out.close();
				tag.flush();
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	public static void main(String[] args) {

	}
}
